#include "toggleswitch.h"
#include <QPainter>
#include <QMouseEvent>
#include <QEasingCurve>
#include <QDebug>

ToggleSwitch::ToggleSwitch(QWidget *parent)
    : QAbstractButton(parent),
    m_pressed(false),
    m_thumbPosition(0),
    m_radius(8.0),
    m_trackColor("#CCCCCC"),
    m_trackActiveColor("#4CAF50"),
    m_trackDisabledColor("#AAAAAA"),
    m_thumbColor("#FFFFFF"),
    m_thumbActiveColor("#FFFFFF"),
    m_borderColor("#999999"),
    m_textColor("#000000"),
    m_textActiveColor("#FFFFFF"),
    m_showText(true),
    m_onText("ON"),
    m_offText("OFF"),
    m_locked(false),
    m_hovering(false)
{
    // 初始化
    setCheckable(true);
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    setCursor(Qt::PointingHandCursor);

    // 禁用默认的外观变化
    setAttribute(Qt::WA_NoMousePropagation);

    // 动画
    m_animation = new QPropertyAnimation(this, "thumbPosition", this);
    m_animation->setDuration(200);
    m_animation->setEasingCurve(QEasingCurve::OutBack); // 弹性效果

    // 确保初始位置正确
    updateThumbTargetPosition(isChecked());

    // 连接信号
    connect(this, &ToggleSwitch::toggled, this, &ToggleSwitch::onToggled);
}

ToggleSwitch::~ToggleSwitch()
{
    delete m_animation;
}

QSize ToggleSwitch::sizeHint() const
{
    return QSize(70, 34);
}

QSize ToggleSwitch::minimumSizeHint() const
{
    return QSize(50, 25);
}

qreal ToggleSwitch::thumbPosition() const
{
    return m_thumbPosition;
}

void ToggleSwitch::setThumbPosition(qreal position)
{
    if (qFuzzyCompare(m_thumbPosition, position))
        return;

    m_thumbPosition = position;
    update();
}

QColor ToggleSwitch::trackColor() const
{
    return m_trackColor;
}

void ToggleSwitch::setTrackColor(const QColor &color)
{
    if (m_trackColor != color) {
        m_trackColor = color;
        update();
    }
}

QColor ToggleSwitch::trackActiveColor() const
{
    return m_trackActiveColor;
}

void ToggleSwitch::setTrackActiveColor(const QColor &color)
{
    if (m_trackActiveColor != color) {
        m_trackActiveColor = color;
        update();
    }
}

QColor ToggleSwitch::thumbColor() const
{
    return m_thumbColor;
}

void ToggleSwitch::setThumbColor(const QColor &color)
{
    if (m_thumbColor != color) {
        m_thumbColor = color;
        update();
    }
}

QColor ToggleSwitch::thumbActiveColor() const
{
    return m_thumbActiveColor;
}

void ToggleSwitch::setThumbActiveColor(const QColor &color)
{
    if (m_thumbActiveColor != color) {
        m_thumbActiveColor = color;
        update();
    }
}

QColor ToggleSwitch::borderColor() const
{
    return m_borderColor;
}

void ToggleSwitch::setBorderColor(const QColor &color)
{
    if (m_borderColor != color) {
        m_borderColor = color;
        update();
    }
}

bool ToggleSwitch::showText() const
{
    return m_showText;
}

void ToggleSwitch::setShowText(bool show)
{
    if (m_showText != show) {
        m_showText = show;
        update();
    }
}

QString ToggleSwitch::onText() const
{
    return m_onText;
}

void ToggleSwitch::setOnText(const QString &text)
{
    if (m_onText != text) {
        m_onText = text;
        update();
    }
}

QString ToggleSwitch::offText() const
{
    return m_offText;
}

void ToggleSwitch::setOffText(const QString &text)
{
    if (m_offText != text) {
        m_offText = text;
        update();
    }
}

bool ToggleSwitch::isLocked() const
{
    return m_locked;
}

void ToggleSwitch::setLocked(bool locked)
{
    if (m_locked != locked) {
        m_locked = locked;
        setCursor(locked ? Qt::ForbiddenCursor : Qt::PointingHandCursor);
        update();
    }
}

void ToggleSwitch::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    const bool enabled = isEnabled();
    const bool checked = isChecked();

    // 1. 确定颜色 - 核心修正点
    QColor trackColor = m_trackColor;
    QColor thumbColor = m_thumbColor;
    QColor borderColor = m_borderColor;
    QColor textColor = m_textColor;

    // 处理锁定状态
    if (m_locked) {
        // 锁定状态下始终显示禁用颜色
        trackColor = m_trackDisabledColor;
        thumbColor = m_trackDisabledColor.lighter(150);
        borderColor = m_trackDisabledColor.darker(120);
        textColor = m_trackDisabledColor.darker(150);
    }
    // 处理激活状态
    else if (enabled && checked) {
        trackColor = m_trackActiveColor;
        thumbColor = m_thumbActiveColor;
        textColor = m_textActiveColor;

        // 悬停效果仅限未锁定状态
        if (m_hovering) {
            thumbColor = thumbColor.lighter(110);
        }
    }
    // 处理悬停效果
    else if (enabled && m_hovering) {
        thumbColor = thumbColor.lighter(110);
        if (!checked) {
            trackColor = trackColor.lighter(95);
        }
    }
    // 处理禁用状态
    else if (!enabled) {
        trackColor = m_trackDisabledColor;
        thumbColor = m_trackDisabledColor.lighter(150);
        borderColor = m_trackDisabledColor.darker(120);
        textColor = m_trackDisabledColor.darker(150);
    }

    // 2. 绘制轨道
    const QRect trackRect = rect().adjusted(1, 1, -1, -1);
    painter.setPen(borderColor);
    painter.setBrush(trackColor);
    painter.drawRoundedRect(trackRect, m_radius, m_radius);

    // 3. 计算滑块位置和尺寸
    const int sliderSize = height() - 6;
    const int yPos = (height() - sliderSize) / 2;
    const qreal maxPosition = width() - sliderSize - 4;

    // 确保滑块位置在有效范围内
    qreal currentPos = m_thumbPosition;
    if (currentPos < 0) currentPos = 0;
    if (currentPos > maxPosition) currentPos = maxPosition;

    // 4. 绘制滑块阴影（仅限未锁定状态）
    if (!m_locked) {
        painter.setPen(Qt::NoPen);
        painter.setBrush(QColor(0, 0, 0, 20));
        painter.drawEllipse(QRectF(currentPos + 2, yPos + 1.5, sliderSize, sliderSize));
    }

    // 5. 绘制滑块
    painter.setPen(m_locked ? borderColor.darker(130) : borderColor);
    painter.setBrush(thumbColor);
    painter.drawEllipse(QRectF(currentPos + 2, yPos, sliderSize, sliderSize));

    // 6. 绘制文本（ON/OFF）
    if (m_showText) {
        painter.setPen(textColor);
        QFont font = painter.font();
        font.setPointSizeF(sliderSize * 0.4);
        font.setBold(true);
        painter.setFont(font);

        const int halfSlider = sliderSize / 2;
        QRect leftTextRect(6, 0, halfSlider, height());
        QRect rightTextRect(width() - halfSlider - 6, 0, halfSlider, height());

        painter.drawText(leftTextRect, Qt::AlignVCenter | Qt::AlignLeft, m_offText);
        painter.drawText(rightTextRect, Qt::AlignVCenter | Qt::AlignRight, m_onText);
    }
}

void ToggleSwitch::mousePressEvent(QMouseEvent *event)
{
    if (m_locked) {
        // 锁定状态下忽略点击事件
        event->ignore();
        return;
    }

    if (event->button() == Qt::LeftButton) {
        // 记录按下状态用于视觉反馈
        m_pressed = true;
        update();

        // 接受事件但不立即改变状态
        event->accept();
    }
}

void ToggleSwitch::mouseReleaseEvent(QMouseEvent *event)
{
    if (m_locked) {
        // 锁定状态下忽略释放事件
        event->ignore();
        return;
    }

    if (event->button() == Qt::LeftButton && m_pressed && underMouse()) {
        m_pressed = false;
        setChecked(!isChecked());
        update();
        event->accept();
    }
}

void ToggleSwitch::enterEvent(QEvent *event)
{
    Q_UNUSED(event)
    if (isEnabled() && !m_locked) {
        m_hovering = true;
        update();
    }
}



void ToggleSwitch::leaveEvent(QEvent *event)
{
    Q_UNUSED(event)
    if (m_hovering) {
        m_hovering = false;
        m_pressed = false; // 离开时重置按下状态
        update();
    }
}

void ToggleSwitch::resizeEvent(QResizeEvent *event)
{
    QAbstractButton::resizeEvent(event);
    updateThumbTargetPosition(isChecked());
}



void ToggleSwitch::onToggled(bool checked)
{
    if (m_locked) return;
    updateThumbTargetPosition(checked);
}

void ToggleSwitch::updateThumbTargetPosition(bool checked)
{
    if (m_locked) return; // 锁定状态下不更新滑块位置

    const int sliderSize = height() - 6;
    const qreal minPos = 0;
    const qreal maxPos = width() - sliderSize - 4;

    if (width() < sliderSize + 4) {
        setThumbPosition(checked ? maxPos : minPos);
        return;
    }

    m_animation->stop();
    m_animation->setStartValue(thumbPosition());
    m_animation->setEndValue(checked ? maxPos : minPos);
    m_animation->start();
}
